package service

import (
	"fmt"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/text/gstr"

	"goframe-zc/dto"
)

// Zlyc 单例模式（全局唯一实例）
var Zlyc = zlycService{}

type zlycService struct{}

// ZlycCenterDay 运营中心每日业绩统计核心逻辑
func (s *zlycService) ZlycCenterDay(ctx g.Ctx) (interface{}, error) {
	// 1. 初始化变量（规范命名，避免模糊变量名）
	var (
		dailyCenterList    []*dto.OperationsCenterDay                      // 每日运营中心表数据
		yesterdayOrders    []*dto.OrderInfo                                // 昨日入单数据
		resultMsg          string                                          // 结果信息
		today              = gtime.Date()                                  // 今日日期（仅年月日，00:00:00）
		yesterday          = gtime.Now().AddDate(0, 0, -1).Format("Y-m-d") // 昨日日期（仅年月日）
		defaultReleaseRate = 0.5                                           // 默认释放参数
	)

	// 2. 检查今日运营中心数据是否已初始化（避免重复插入）
	if err := s.initDailyCenterIfNotExist(ctx, gtime.NewFromStr(today), defaultReleaseRate, &dailyCenterList); err != nil {
		return nil, gerror.Wrap(err, "初始化每日运营中心数据失败")
	}

	// 3. 查询昨日入单数据（优化SQL条件，避免字符串拼接注入风险）
	if err := s.queryYesterdayOrders(ctx, gtime.NewFromStr(yesterday), gtime.NewFromStr(today), &yesterdayOrders); err != nil {
		return nil, gerror.Wrap(err, "查询昨日入单数据失败")
	}
	if len(yesterdayOrders) == 0 {
		return "昨日入单数据为空", nil
	}
	// 4. 遍历订单，更新对应运营中心的昨日业绩
	if err := s.updateCenterYesterdayPerformance(ctx, yesterdayOrders, dailyCenterList, &resultMsg); err != nil {
		return nil, gerror.Wrap(err, "更新运营中心昨日业绩失败")
	}

	return resultMsg, nil
}

// initDailyCenterIfNotExist 初始化今日运营中心数据（不存在则插入）
func (s *zlycService) initDailyCenterIfNotExist(
	ctx g.Ctx,
	today *gtime.Time,
	defaultReleaseRate float64,
	dailyCenterList *[]*dto.OperationsCenterDay,
) error {
	// 查询今日是否已存在数据
	todayNow := today.Format("Y-m-d")
	fmt.Println("today:", todayNow)
	err := g.DB("default").Model("operations_center_day").
		Where("day", todayNow).
		Scan(dailyCenterList)
	if err != nil {
		return gerror.Wrap(err, "查询每日运营中心数据失败")
	}

	// 已存在则直接返回
	if len(*dailyCenterList) > 0 {
		return nil
	}

	// 不存在则从运营中心基础表查询数据
	var centerList []*dto.OperationsCenterDayInsert
	err = g.DB("mysql_zlyc").Model("operations_center").Scan(&centerList)
	if err != nil {
		return gerror.Wrap(err, "查询运营中心基础数据失败")
	}
	if len(centerList) == 0 {
		return gerror.New("运营中心基础表无数据")
	}

	// 补充每日数据字段（日期、默认释放参数）
	for _, center := range centerList {
		center.Day = today
		center.ReleaseParameter = defaultReleaseRate
	}

	// 批量插入每日运营中心数据
	_, err = g.DB("default").Model("operations_center_day").
		Data(centerList).
		Insert()
	if err != nil {
		return gerror.Wrap(err, "插入每日运营中心数据失败")
	}

	// 重新查询插入后的数据，赋值给dailyCenterList
	return g.DB("default").Model("operations_center_day").
		Where("day", todayNow).
		Scan(dailyCenterList)
}

// queryYesterdayOrders 查询昨日入单数据（优化SQL条件构造）
func (s *zlycService) queryYesterdayOrders(
	ctx g.Ctx,
	yesterday, today *gtime.Time,
	yesterdayOrders *[]*dto.OrderInfo,
) error {
	yesterdayStr := yesterday.Format("Y-m-d")
	todayStr := today.Format("Y-m-d")
	// 用ORM条件构造器替代字符串拼接，避免SQL注入，更安全
	return g.DB("mysql_zlyc").Model("order_info").
		Where("order_type", 1).
		WhereIn("status", []int{2, 3, 4}).
		WhereGTE("order_paid_time", yesterdayStr).
		WhereLT("order_paid_time", todayStr).
		Scan(yesterdayOrders)
}

// updateCenterYesterdayPerformance 遍历订单更新运营中心昨日业绩
func (s *zlycService) updateCenterYesterdayPerformance(
	ctx g.Ctx,
	yesterdayOrders []*dto.OrderInfo,
	dailyCenterList []*dto.OperationsCenterDay,
	resultMsg *string,
) error {
	// 构建运营中心名称->数据的映射，避免循环嵌套查询（优化性能）
	centerMap := make(map[string]*dto.OperationsCenterDay, len(dailyCenterList))
	for _, center := range dailyCenterList {
		centerMap[center.Name] = center
	}

	// 遍历每笔昨日订单
	for _, order := range yesterdayOrders {
		var operationsCenterDay *dto.OperationsCenterDay
		// 查询订单所属用户
		user, err := s.getUserByOrderUserId(ctx, order.UserId)
		if err != nil {
			return gerror.Wrapf(err, "查询订单[%d]所属用户[%d]失败", order.Id, order.UserId)
		}

		// 获取用户上级运营中心
		superiorCenter, err := s.getSuperiorOperationCenter(ctx, user.Shared)
		if err != nil {
			return gerror.Wrapf(err, "获取用户[%d]上级运营中心失败", user.Id)
		}
		if superiorCenter == nil || gstr.LenRune(superiorCenter.Name) < 1 {
			return gerror.Newf("用户[%d]未找到上级运营中心", user.Id)
		}

		// 从映射中获取对应运营中心每日数据（避免循环遍历）
		dailyCenter, exist := centerMap[superiorCenter.Name]
		if !exist {
			return gerror.Newf("运营中心[%s]未找到今日统计数据", superiorCenter.Name)
		}
		// 查询每个运营商当前订单金额
		err2 := g.DB("default").Model("operations_center_day").
			Where("id", dailyCenter.Id).
			Scan(&operationsCenterDay)
		if err2 != nil {
			return err2
		}
		// 计算累计业绩和释放比例
		totalPerformance := operationsCenterDay.YesterdayOrderPrice + order.Price
		releaseRate := s.getRate(totalPerformance)

		// 构建更新备注
		remark := fmt.Sprintf(
			"%s;订单id:%d,订单金额:%.2f,用户id:%d,上级运营商:%s",
			operationsCenterDay.Remark, order.Id, order.Price, order.UserId, superiorCenter.Name,
		)

		// 执行更新操作
		if err := s.updateDailyCenterPerformance(ctx, dailyCenter.Id, totalPerformance, releaseRate, remark); err != nil {
			return gerror.Wrapf(err, "更新运营中心[%s]业绩失败", superiorCenter.Name)
		}

		// 拼接结果信息
		*resultMsg += fmt.Sprintf("%s;", remark)
	}

	return nil
}

// getUserByOrderUserId 根据订单的userId查询用户信息
func (s *zlycService) getUserByOrderUserId(ctx g.Ctx, userId int) (*dto.UserInfo, error) {
	var user dto.UserInfo
	err := g.DB("mysql_zlyc").Model("user_info").
		Where("id", userId).
		Scan(&user)
	if err != nil {
		return nil, gerror.Wrapf(err, "查询用户[%d]信息失败", userId)
	}
	if user.Id == 0 {
		return nil, gerror.Newf("用户[%d]不存在", userId)
	}
	return &user, nil
}

// updateDailyCenterPerformance 更新运营中心每日业绩
func (s *zlycService) updateDailyCenterPerformance(
	ctx g.Ctx,
	centerId int,
	totalPerformance, releaseRate float64,
	remark string,
) error {
	_, err := g.DB("default").Model("operations_center_day").
		Where("id", centerId).
		Data(g.Map{
			"yesterday_order_price": totalPerformance,
			"release_parameter":     releaseRate,
			"remark":                remark,
			"update_time":           gtime.Now(), // 补充更新时间（可选，优化审计）
		}).
		Update()
	return err
}

// getSuperiorOperationCenter 获取用户上级运营中心（原逻辑保留，优化错误处理）
func (s *zlycService) getSuperiorOperationCenter(ctx g.Ctx, userId int) (*dto.UserOperationsJoin, error) {
	var (
		user       dto.UserInfo
		centerJoin dto.UserOperationsJoin
		// 移除全局变量userInfo2，改为局部变量，避免并发安全问题
	)

	// 查询当前用户信息
	err := g.DB("mysql_zlyc").Model("user_info").
		Where("id", userId).
		Scan(&user)
	if err != nil {
		return nil, gerror.Wrapf(err, "查询上级用户[%d]信息失败", userId)
	}
	if user.Id == 0 {
		return nil, nil // 无上级用户，返回nil（原逻辑保留）
	}

	// 查询用户对应的运营中心
	err = g.DB("mysql_zlyc").Model("user_info u").
		LeftJoin("operations_center c", "c.user_id = u.id").
		Where("u.id", user.Id).
		Fields("c.name, u.id, u.user_type").
		Scan(&centerJoin)
	if err != nil {
		return nil, gerror.Wrapf(err, "查询用户[%d]关联运营中心失败", user.Id)
	}

	// 若当前用户不是运营中心（user_type≠4），递归查询上级
	if centerJoin.UserType != 4 || gstr.LenRune(centerJoin.Name) < 1 {
		return s.getSuperiorOperationCenter(ctx, user.Shared)
	}

	return &centerJoin, nil
}

// getRate 根据业绩获取释放比例（原逻辑完全保留）
func (s *zlycService) getRate(price float64) float64 {
	if price >= 14995 {
		return 1.0
	} else if price >= 9998 {
		return 0.8
	}
	return 0.5
}

/*************************************************************/

// ZlycJxyWithdraw 智链影创-棘祥源平移-未入单用户提现统计
func (s *zlycService) ZlycJxyWithdraw(ctx g.Ctx) (interface{}, error) {
	// 1. 初始化变量（规范命名，避免模糊变量名）
	var jxyUserSumList []*dto.JxyUserSum
	// 2.查询统计数据
	// 查询未入单用户提现统计
	err := g.DB("mysql_zlyc").Model("zlyc_migrate_users m").
		LeftJoin("user_info u", "u.username = m.zlyc_phone").
		Where("m.status = 1 and m.res like '%注册成功%'").
		Where("u.user_type = 1").
		//Where("u.user_bank_name = ?", "丁和云").
		Fields("u.id,u.user_bank_name,u.green_points_amount,u.consumption_points_amount").
		Group("u.id").
		Order("u.user_bank_name asc").
		Scan(&jxyUserSumList)
	if err != nil {
		return nil, gerror.Wrapf(err, "查询zlyc_migrate_users失败")
	}
	for _, user := range jxyUserSumList {
		var jxyUserSum *dto.JxyUserSum

		err := g.DB("default").Model("jxy_user_sum m").
			Where("m.user_bank_name = ?", user.UserBankName).
			Scan(&jxyUserSum)
		if err != nil {
			return nil, gerror.Wrapf(err, "查询jxy_user_sum失败")
		}
		// 查询提现总金额
		sum, err := g.DB("mysql_zlyc").Model("withdrawal_approval a").
			Where("a.user_id = ?", user.Id).
			Where("a.status = ?", 2).
			Sum("withdrawal_amount")
		if err != nil {
			return nil, gerror.Wrapf(err, "withdrawal_approval失败")
		}
		if jxyUserSum == nil || user.UserBankName == "" {
			insertData := g.Map{
				"zlyc_ids":                  fmt.Sprintf("%d", user.Id),
				"user_bank_name":            user.UserBankName,
				"green_points_amount":       user.GreenPointsAmount,
				"consumption_points_amount": user.ConsumptionPointsAmount,
				"withdrawal_amount":         sum,
			}
			g.Dump("insertData:", insertData)
			_, err := g.DB("default").Model("jxy_user_sum").Data(insertData).Insert()
			if err != nil {
				return nil, gerror.Wrapf(err, "插入jxy_user_sum失败")
			}
		} else {
			jxyUserSum.ZlycIds = fmt.Sprintf("%s、%d", jxyUserSum.ZlycIds, user.Id)
			jxyUserSum.GreenPointsAmount = jxyUserSum.GreenPointsAmount + user.GreenPointsAmount
			jxyUserSum.ConsumptionPointsAmount = jxyUserSum.ConsumptionPointsAmount + user.ConsumptionPointsAmount
			jxyUserSum.WithdrawTotal = jxyUserSum.WithdrawTotal + sum
			_, err := g.DB("default").Model("jxy_user_sum").Where("id = ?", jxyUserSum.Id).Data(&jxyUserSum).Update()
			if err != nil {
				return nil, gerror.Wrapf(err, "更新jxy_user_sum失败")
			}
		}

	}
	return "处理成功,请去jxy_user_sum表查看", nil
}
